% produce the adjusted generator base on
% Israel, R.B, Rosenthal, J.S., Wei, J.Z. (2000). Finding Generators for
% Markov Chains via Empirical Transition Matrices, with Application
% to Credit Ratings. Mathematical Finance 11 (2001), 245-265.

clear all
clc

%load('D:\My Documents\CIRANO\db_mySQL\tp_2010Dec11_MR7.mat','cohTpGrp','conditions','numEdges','year_list');
load('D:\My Documents\CIRANO\db_mySQL\tp_2012Mar5_MR7_WR.mat','cohTpGrpStd','conditions','numEdgesStd','year_list', 'avgCohTpGrpStd');
numEdges = numEdgesStd;
cohTpGrp = cohTpGrpStd;

lamdaAdj = zeros(length(conditions), length(year_list)-1,numEdges,numEdges );

for yr =1: length(year_list)-1;
    
    for grp = 1: length(conditions)
        TP (:,:) =  cohTpGrp(grp, yr, :,:)/100;
        lamdaPre = generatorPre(TP, 500);
        lamdaAdj(grp, yr,:,:) = lamdaPre;
        diagInd = logical(eye(numEdges,numEdges));
        x = lamdaPre;
        x(diagInd) = 0;
        
        if ~isempty( find(x<0, 1)) % return 1 if true
            disp( strcat([ 'year ' num2str(yr) ' Group ' num2str(grp) ' has negative off-diagonal entries']));
            for i = 1: numEdges
                % check every row with negative off-diagonal elements
                if ~isempty(find(x(i,:)<0, 1))
                    xx = x(i,:);
                    G = 0;
                    B = 0;
                    for j = 1:numEdges
                        G = G + max(0,x(i,j));
                        B = B + max(0,-x(i,j));
                    end
                    G = G + abs(lamdaPre(i,i));
                    
                    % adjust generator with negtaive off-diagonal elements
                    if G>0
                        neg = (x(i,:)<0) ;
                        xx(neg) = 0;
                        xx(:,i) = lamdaPre(i,i);
                        xx = xx - (B/G)* xx;
                    else
                        xx(:,i) = lamdaPre(i,i);
                    end
                    lamdaAdj(grp, yr,i,:) = xx;                  
                    
                end
            end
            
        end
        
    end
end

save('D:\My Documents\CIRANO\db_mySQL\CohLamdaAdjStd.mat');

% lamda for avg matrices
lamdaAdj = zeros(length(conditions),numEdges,numEdges );
for grp = 1: length(conditions)
        TP (:,:) =  avgCohTpGrpStd(grp, :,:)/100;
        lamdaPre = generatorPre(TP, 500);
        lamdaAdj(grp, :,:) = lamdaPre;
        diagInd = logical(eye(numEdges,numEdges));
        x = lamdaPre;
        x(diagInd) = 0;
        
        if ~isempty( find(x<0, 1)) % return 1 if true
            disp( strcat([ 'year ' num2str(yr) ' Group ' num2str(grp) ' has negative off-diagonal entries']));
            for i = 1: numEdges
                % check every row with negative off-diagonal elements
                if ~isempty(find(x(i,:)<0, 1))
                    xx = x(i,:);
                    G = 0;
                    B = 0;
                    for j = 1:numEdges
                        G = G + max(0,x(i,j));
                        B = B + max(0,-x(i,j));
                    end
                    G = G + abs(lamdaPre(i,i));
                    
                    % adjust generator with negtaive off-diagonal elements
                    if G>0
                        neg = (x(i,:)<0) ;
                        xx(neg) = 0;
                        xx(:,i) = lamdaPre(i,i);
                        xx = xx - (B/G)* xx;
                    else
                        xx(:,i) = lamdaPre(i,i);
                    end
                    lamdaAdj(grp,i,:) = xx;                  
                    
                end
            end
            
        end
        
 end